package com.hkts.management.returnfee.service.serviceimpl;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.hkts.management.cargoapply.entity.HktsCargoApply;
import com.hkts.management.cargoapply.mapper.HktsCargoApplyMapper;
import com.hkts.management.common.utils.SnowFlakeUtil;
import com.hkts.management.model.enums.OrderTypeEnum;
import com.hkts.management.order.entity.HktsOrder;
import com.hkts.management.order.mapper.HktsOrderMapper;
import com.hkts.management.pay.entity.HktsPayRecord;
import com.hkts.management.pay.mapper.HktsPayRecordMapper;
import com.hkts.management.returnfee.entity.HktsReturnFail;
import com.hkts.management.returnfee.mapper.HktsReturnFailMapper;
import com.hkts.management.returnfee.service.IHktsReturnFailService;
import com.hkts.management.utils.PayConstants;
import com.hkts.management.utils.PayProperties;
import com.xunhu.hupj.pay.sdk.DefaultXunhuPayClient;
import com.xunhu.hupj.pay.sdk.NotifyHandler;
import com.xunhu.hupj.pay.sdk.notify.RefundNotifyParameter;
import com.xunhu.hupj.pay.sdk.request.OrderRefundRequest;
import com.xunhu.hupj.pay.sdk.response.OrderRefundResponse;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.servlet.http.HttpServletRequest;
import java.time.LocalDateTime;
import java.util.List;

/**
 * <p>
 * 服务实现类
 * </p>
 *
 * @author hml
 * @since 2021-05-21
 */
@Service
@Transactional
@Slf4j
public class HktsReturnFailServiceImpl extends ServiceImpl<HktsReturnFailMapper, HktsReturnFail> implements IHktsReturnFailService {


    @Autowired
    private HktsReturnFailMapper hktsReturnFailMapper;
    @Autowired
    private PayProperties payProperties;
    @Autowired
    private HktsCargoApplyMapper hktsCargoApplyMapper;
    @Autowired
    private HktsOrderMapper hktsOrderMapper;
    @Autowired
    private HktsPayRecordMapper hktsPayRecordMapper;

    @Override
    public IPage<HktsReturnFail> selectPage(Page<HktsReturnFail> page, HktsReturnFail hktsReturnFail) {
        QueryWrapper<HktsReturnFail> query = Wrappers.query();
        QueryWrapper<HktsReturnFail> entityWrapper = getEntityWrapper(query, hktsReturnFail);
        return hktsReturnFailMapper.selectPage(page, entityWrapper);
    }


    @Override
    public List<HktsReturnFail> selectList(HktsReturnFail hktsReturnFail) {
        QueryWrapper<HktsReturnFail> query = Wrappers.query();
        QueryWrapper<HktsReturnFail> entityWrapper = getEntityWrapper(query, hktsReturnFail);
        return hktsReturnFailMapper.selectList(entityWrapper);
    }

    /**
     * 公共查询条件
     *
     * @param entityWrapper
     * @return
     */
    public QueryWrapper<HktsReturnFail> getEntityWrapper(QueryWrapper<HktsReturnFail> entityWrapper, HktsReturnFail hktsReturnFail) {
        //条件拼接

        /*if (StringUtils.isNotBlank(hktsReturnFail.getApplayId())) {
            entityWrapper.like(HktsReturnFail.APPLAY_ID, hktsReturnFail.getApplayId());
        }*/
        return entityWrapper;
    }

    @Override
    public void returnFee(HktsCargoApply apply) {
        DefaultXunhuPayClient client = new DefaultXunhuPayClient(payProperties.getSecurityKey());
        OrderRefundRequest request = new OrderRefundRequest();
        request.setMchid(payProperties.getMchid());
        request.setNotify_url(payProperties.getRefundNoticeUrl());
        request.setOrder_id(apply.getPayOrder());
        request.setOut_trade_no(apply.getId());
        request.setOut_refund_no(String.valueOf(SnowFlakeUtil.getFlowIdInstance().nextId()));
        request.setRefund_desc("取消订单");
        Float v = apply.getDeposit().floatValue() * 100;
        request.setRefund_fee(v.intValue());
        request.setNonce_str(String.valueOf(SnowFlakeUtil.getFlowIdInstance().nextId()));
        System.out.println(request.toString());
        //获取报名数据
        QueryWrapper<HktsOrder> query = Wrappers.query();
        query.lambda().eq(HktsOrder::getApplyId, apply.getId());
        HktsOrder hktsOrder = hktsOrderMapper.selectOne(query);


        HktsPayRecord hktsPayRecord = new HktsPayRecord();
        hktsPayRecord.setId(String.valueOf(SnowFlakeUtil.getFlowIdInstance().nextId()));
        hktsPayRecord.setDriverId(apply.getDriverId());
        hktsPayRecord.setCompanyCode(hktsOrder.getCompanyCode());
        hktsPayRecord.setDeposit(apply.getDeposit());
        hktsPayRecord.setCreateTime(LocalDateTime.now());
        hktsPayRecord.setPayStatus("2");
        hktsPayRecord.setOrderId(hktsOrder.getId());
        hktsPayRecordMapper.insert(hktsPayRecord);
        /*
         * 调用退款接口
         * */
        try {
            log.info("退款参数：{}", request);
            OrderRefundResponse refund = client.refund(request);
        } catch (Exception e) {
            /*
             * 调用失败将该数据传入退款失败表
             * */
            HktsReturnFail fail = new HktsReturnFail();
            fail.setApplyId(apply.getId());
            fail.setId(String.valueOf(SnowFlakeUtil.getFlowIdInstance().nextId()));
            fail.setCreateTime(LocalDateTime.now());
            fail.setReasonsForRefund("拒绝订单");
            hktsReturnFailMapper.insert(fail);
        }
    }

    @Override
    public String refundNoticeUrl(HttpServletRequest request) {
        RefundNotifyParameter refundNotifyParameter = NotifyHandler.handleRefundNotify(request, payProperties.getSecurityKey());
        log.info("退款返回数据{}", refundNotifyParameter);
        try {
            String refund_status = refundNotifyParameter.getRefund_status();
            if (!refund_status.equals("SUCCESS")) {
                addHktsReturnFail(refundNotifyParameter.getOut_trade_no());
                return "error";
            } else {
                /*
                 * 退费成功查看是否有失败记录
                 * 有的话删除
                 * */
                HktsCargoApply hktsCargoApply = hktsCargoApplyMapper.selectById(refundNotifyParameter.getOut_trade_no());
                hktsCargoApply.setRefundOrder(refundNotifyParameter.getRefund_id());
                hktsCargoApply.setDepositStatus(PayConstants.REFUND);
                hktsCargoApply.setUpdateTime(LocalDateTime.now());
                hktsCargoApplyMapper.updateApplyById(hktsCargoApply);
                //根据报名查订单
                QueryWrapper<HktsOrder> orderQuery = Wrappers.query();
                orderQuery.lambda().eq(HktsOrder::getApplyId, hktsCargoApply.getId());
                HktsOrder hktsOrder = hktsOrderMapper.selectOne(orderQuery);
                hktsOrder.setOrderStatus(OrderTypeEnum.CANCEL);
                hktsOrderMapper.updateByOrderId(hktsOrder.getId(), OrderTypeEnum.CANCEL, 8, LocalDateTime.now());

                //判断是否有失败记录
                QueryWrapper<HktsReturnFail> failQuery = Wrappers.query();
                failQuery.lambda().eq(HktsReturnFail::getApplyId, hktsCargoApply.getId());
                List<HktsReturnFail> hktsReturnFails = hktsReturnFailMapper.selectList(failQuery);
                if (hktsReturnFails.size() > 0) {
                    hktsReturnFailMapper.delete(failQuery);
                }
                //跟新信息支付记录表
                QueryWrapper<HktsPayRecord> query = Wrappers.query();
                query.lambda().eq(HktsPayRecord::getOrderId, hktsOrder.getId());
                query.lambda().eq(HktsPayRecord::getPayStatus, "2");
                HktsPayRecord hktsPayRecord = hktsPayRecordMapper.selectOne(query);
                if (hktsPayRecord == null) {
                    hktsPayRecord = new HktsPayRecord();
                    hktsPayRecord.setId(String.valueOf(SnowFlakeUtil.getFlowIdInstance().nextId()));
                    hktsPayRecord.setDriverId(hktsCargoApply.getDriverId());
                    hktsPayRecord.setCompanyCode(hktsOrder.getCompanyCode());
                    hktsPayRecord.setDeposit(hktsCargoApply.getDeposit());
                    hktsPayRecord.setCreateTime(LocalDateTime.now());
                    hktsPayRecord.setPayStatus("3");
                    hktsPayRecord.setPayOrder(hktsCargoApply.getRefundOrder());
                    hktsPayRecord.setSuccessTime(LocalDateTime.now());
                    hktsPayRecord.setOrderId(hktsOrder.getId());
                    hktsPayRecordMapper.insert(hktsPayRecord);
                } else {
                    hktsPayRecord.setPayOrder(hktsCargoApply.getRefundOrder());
                    hktsPayRecord.setPayStatus("3");
                    hktsPayRecord.setSuccessTime(LocalDateTime.now());
                    hktsPayRecordMapper.updatePayRecordById(hktsPayRecord);
                }
            }
        } catch (Exception e) {
            e.printStackTrace();
            addHktsReturnFail(refundNotifyParameter.getOut_trade_no());
            return "error";
        }
        return "success";
    }
    /*
     * 轮询处理退费失败订单
     * */

    @Override
    public void handlerFaileRefund() {
        HktsReturnFail fail = new HktsReturnFail();
        List<HktsReturnFail> hktsReturnFails = selectList(fail);
        System.out.println("---------处理退费失败报名费------------");
        /*
         * 循环退费
         * */
        hktsReturnFails.stream().forEach(fails -> {
            try {
                HktsCargoApply hktsCargoApply = hktsCargoApplyMapper.selectById(fails.getApplyId());
                DefaultXunhuPayClient client = new DefaultXunhuPayClient(payProperties.getSecurityKey());
                OrderRefundRequest request = new OrderRefundRequest();
                request.setMchid(payProperties.getMchid());
                request.setNotify_url(payProperties.getRefundNoticeUrl());
                request.setOrder_id(hktsCargoApply.getPayOrder());
                request.setOut_trade_no(hktsCargoApply.getId());
                request.setOut_refund_no(String.valueOf(SnowFlakeUtil.getFlowIdInstance().nextId()));
                request.setRefund_desc(fails.getReasonsForRefund());
                Float v = hktsCargoApply.getDeposit().floatValue() * 100;
                request.setRefund_fee(v.intValue());
                request.setNonce_str(String.valueOf(SnowFlakeUtil.getFlowIdInstance().nextId()));
                System.out.println(request.toString());
            } catch (Exception e) {
                e.printStackTrace();
            }
        });
    }

    /*
     * 新增失败记录
     * */
    public void addHktsReturnFail(String applayId) {
        HktsReturnFail hktsReturnFail = new HktsReturnFail();
        hktsReturnFail.setApplyId(applayId);
        QueryWrapper<HktsReturnFail> query = Wrappers.query();
        QueryWrapper<HktsReturnFail> entityWrapper = getEntityWrapper(query, hktsReturnFail);
        Integer integer = hktsReturnFailMapper.selectCount(entityWrapper);
        if (integer < 1) {
            HktsReturnFail fail = new HktsReturnFail();
            fail.setApplyId(applayId);
            fail.setId(String.valueOf(SnowFlakeUtil.getFlowIdInstance().nextId()));
            fail.setCreateTime(LocalDateTime.now());
            fail.setReasonsForRefund("拒绝订单！");
            hktsReturnFailMapper.insert(fail);
        }
    }
}